﻿using Hicap.AuthorizationServer.Core.Common;
using Hicap.AuthorizationServer.Core.Managers.Authorization;
using IdentityServer4.Models;
using IdentityServer4.Validation;
using System.Threading.Tasks;

namespace Hicap.AuthorizationServer.Core.IdentityServer
{
    public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
    {
        private readonly ILogInManager _logInManager;
        private readonly LoginResultTypeHelper _loginResultTypeHelper;

        public ResourceOwnerPasswordValidator(ILogInManager logInManager, LoginResultTypeHelper loginResultTypeHelper)
        {
            _logInManager = logInManager;
            _loginResultTypeHelper = loginResultTypeHelper;
        }

        public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
        {
            return Task.Run(async () =>
            {
                GrantValidationResult loginResult = await GetLoginResultAsync(
                    context.UserName,
                    context.Password
                );

                context.Result = loginResult;
            });
        }

        private async Task<GrantValidationResult> GetLoginResultAsync(string userCode, string password)
        {
            LoginResult loginResult = await _logInManager.LoginAsync(userCode, password);

            switch (loginResult.Result)
            {
                case LoginResultType.Success:
                    return new GrantValidationResult(
                        subject: loginResult.User.UserCode,
                        authenticationMethod: "custom",
                        claims: loginResult.Identity.Claims);

                default:
                    return new GrantValidationResult(TokenRequestErrors.InvalidGrant, _loginResultTypeHelper.CreateExceptionForFailedLoginAttempt(loginResult.Result, userCode).Message);
            }
        }
    }
}